package com.hm.hall.commons.interceptors;


import com.hm.hall.commons.dao.AccessLogMapper;
import com.hm.hall.commons.util.ActionUtils;
import com.hm.hall.commons.util.IPUtil;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Enumeration;
import java.util.Map;

/**
 * 拦截请求日志的调试类
 *
 * @author wei
 */

@Component
public class DebugLogInterceptor extends HandlerInterceptorAdapter {

    Logger log = Logger.getLogger(DebugLogInterceptor.class);

    @Autowired
    AccessLogMapper accessLogMapper;


    public static String getRequestParamJSON(HttpServletRequest request) {
        StringBuilder handlerInfo = new StringBuilder("{");
        @SuppressWarnings("rawtypes")
        Enumeration en = request.getParameterNames();
        if (en != null) {
            while (en.hasMoreElements()) {
                String paramName = (String) en.nextElement();
                handlerInfo.append(" \"").append(paramName).append("\":\"").append(request.getParameter(paramName)).append("\",");
            }
            handlerInfo.deleteCharAt(handlerInfo.length() - 1).append("}");
        }
        return handlerInfo.toString();
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String requestURI = request.getRequestURI();
        String remoteAddr = IPUtil.getIpAddr();
        String handlerName = "";
        if (handler instanceof HandlerMethod) {
            HandlerMethod ha = (HandlerMethod) handler;
            // 只有 Response 是取不到的,放入request 中
            ActionUtils.setResponse(response);
            String className = ha.getMethod().getDeclaringClass().getName();
            handlerName = className.substring(className.lastIndexOf(".") + 1) + "." + ha.getMethod().getName();
        } else if (handler instanceof ResourceHttpRequestHandler) {
            ResourceHttpRequestHandler ha = (ResourceHttpRequestHandler) handler;
            handlerName = ha.getLocations().toString();
        }
        log.info("\n*****************************************************************");
        StringBuilder handlerInfo = new StringBuilder(String.format("[url:%s] [IP:%s] [handler:%s]\t%s", requestURI, remoteAddr, handlerName, getRequestParamJSON(request)));
        log.info(handlerInfo.toString());
        //访问数据统计表
        return true;
    }

    private String paramValue(Map parameterMap, String name) {
        String[] string = (String[]) parameterMap.get(name);
        if (string == null) {
            return "";
        } else {
            return string[0];
        }
    }

    @Override
    public void postHandle(HttpServletRequest request,
                           HttpServletResponse response, Object handler,
                           ModelAndView modelAndView) throws Exception {


    }

    /**
     * 该方法也是需要当前对应的Interceptor的preHandle方法的返回值为true时才会执行。该方法将在整个请求完成之后，
     * 也就是DispatcherServlet渲染了视图执行，
     * 这个方法的主要作用是用于清理资源的，当然这个方法也只能在当前这个Interceptor的preHandle方法的返回值为true时才会执行。
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 输出下返回值,  只有在开发阶段才输出!!
        /*if (!ActionUtils.isDevEnv()) {
            return;
        }
        // 为了取得 输出 response里的内容真是..真是 千辛万苦,丧心病狂
        ResponseWrapper wrapper = new ResponseWrapper(response);
        String result = wrapper.getResponseData();
        response.getOutputStream().write(result.getBytes());
        // 只输出 json格式的数据
        if (result.charAt(0) == '{') {
            result = String.format("\n<--\t\trespons\t\t[%s]\t\t%s", Thread.currentThread().getName(), result);
            log.info(result);
        }*/
    }
}

